package com.jsss.echarts.service;

import com.jsss.common.BusinessException;
import com.jsss.common.ErrorCode;
import com.jsss.echarts.annotation.ChineseName;
import com.jsss.echarts.entity.*;
import com.jsss.utils.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.sql.Date;
import java.util.*;

@Service
public class DataService implements Constant, ErrorCode {


    @Autowired
    RedisTemplate redisTemplate;

    Integer limit=5;


    //返回数据链表
    public HashMap<String,ArrayList> searchMap(Integer userId,String action){
        HashMap<String,ArrayList> map=new LinkedHashMap<>();

        List<EldData> dataList = search(userId,action);

        Class<?> dataClass=null;

        switch (action){
            case "General":         dataClass= GeneralData.class;           break;
            case "BloodPressure":   dataClass= BloodPressureData.class;     break;
            case "BloodRoutine":    dataClass= BloodRoutineData.class;      break;
            case "LiverFunction":   dataClass= LiverFunctionData.class;     break;
            case "RenalFunction":   dataClass= RenalFunctionData.class;     break;
            case "BloodLipid":      dataClass= BloodLipidData.class;        break;
            case "BloodGlucose":    dataClass= BloodGlucoseData.class;      break;
            default: throw new BusinessException(PARAMETER_ERROR,"参数错误");
        }

        // 获取 EldData 子类的所有被ChineseName注解的属性名
        List<String> fieldNames = new ArrayList<>();
        Field[] subDataFields = dataClass.getDeclaredFields();

        for (Field field : subDataFields) {
            //添加是否有注解的判断
            ChineseName chineseNameAnnotation = field.getAnnotation(ChineseName.class);
            if (chineseNameAnnotation!=null){
                fieldNames.add(field.getName());
                map.put(field.getAnnotation(ChineseName.class).value(), new ArrayList<>());
            }
        }

        //添加父类EldData的属性
        List<String> eldDataFieldNames = new ArrayList<>();
        Class<?> eldDataClass=EldData.class;
        Field[] eldDataFields = eldDataClass.getDeclaredFields();

        for (Field field : eldDataFields) {
            //添加是否有注解的判断
            ChineseName chineseNameAnnotation = field.getAnnotation(ChineseName.class);
            if (chineseNameAnnotation!=null){
                eldDataFieldNames.add(field.getName());
                map.put(field.getAnnotation(ChineseName.class).value(), new ArrayList<>());
            }
        }

        for (EldData data : dataList) {
            //添加子类的链表
            for (String fieldName : fieldNames) {
                try {
                    Field field = dataClass.getDeclaredField(fieldName);
                    field.setAccessible(true);
                    ArrayList<Object> rowData =map.get(field.getAnnotation(ChineseName.class).value());
                    rowData.add(field.get(data));

                    map.put(field.getAnnotation(ChineseName.class).value(),rowData);

                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            //添加父类的链表
            for (String fieldName : eldDataFieldNames) {
                try {
                    Field field = eldDataClass.getDeclaredField(fieldName);
                    field.setAccessible(true);
                    ArrayList<Object> rowData =map.get(field.getAnnotation(ChineseName.class).value());
                    rowData.add(field.get(data));

                    map.put(field.getAnnotation(ChineseName.class).value(),rowData);

                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }


        return map;
    }

    //搜索数据
    public List<EldData> search(Integer userId,String action) {
        String key= ELD_DATA +action+":"+userId;
        Set set = redisTemplate.opsForZSet().reverseRange(key, 0, limit-1);// 获取分数最高的limit个数据
        if(set==null){
            return new ArrayList<>();
        }
        ArrayList<EldData> resList = new ArrayList<>(set);
        Collections.reverse(resList);
        return resList;

    }

    // 将数据存储到有序集合中，分数为日期的时间戳
    public boolean addData(Integer userId, String action,EldData data) {
        String key= ELD_DATA + action + ":" + userId;
        return redisTemplate.opsForZSet().add(key, data,data.getDate().getTime());
    }

    // 更新数据，先删除数据，后增加新数据
    public boolean updateData(Integer userId,EldData oldData,EldData newData) {
        long res=removeData(userId,oldData);
        if (res==0){
            //没有旧数据，就修改失败
            return false;
        }
        return addData(userId, "",newData);
    }

    // 删除指定的数据
    public long removeData(Integer userId, EldData data) {
        String key= ELD_DATA +userId;
        return redisTemplate.opsForZSet().remove(key, data);
    }


    public void update(Integer userId,String action, String data1, String data2, String data3, String data4, String newData1, String newData2, String newData3, String newData4) {

        EldData oldData=initEldData(action, data1, data2, data3, data4);
        System.out.println(oldData);

        EldData newData=initEldData(action, newData1, newData2, newData3, newData4);
        System.out.println(newData);

        boolean res = updateData(userId,oldData,newData);
        System.out.println(res);


    }

    public EldData initEldData(String action, String data1, String data2, String data3, String data4){


        EldData eldData=null;
        switch (action){
            case "General":
                eldData=new GeneralData(Double.parseDouble(data1),Integer.parseInt(data2));
                eldData.setDate(Date.valueOf(data3));
                break;
            case "BloodPressure":
                break;
            case "BloodRoutine":
                break;
            case "LiverFunction":
                break;
            case "RenalFunction":
                break;
            case "BloodLipid":
                break;
            case "BloodGlucose":
                break;


        }
        if (eldData==null){
            throw new BusinessException(PARAMETER_ERROR,"参数错误");
        }


        return eldData;

    }
}
